<?php
namespace App\Http\Controllers\Home;

use Cache;

class jsController extends BaseController
{
    /**
     * 应用ID.
     *
     * @var string
     */
    protected $appId;

    /**
     * 应用secret.
     *
     * @var string
     */
    protected $appSecret;

    /**
     * Cache对象
     *
     * @var Cache
     */
    protected $cache;

    /**
     * 当前URL.
     *
     * @var string
     */
    protected $url;

    const API_TICKET = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi';

    public function __construct()
    {
        parent::__construct();
//        $model_class = Model('mb_payment');
//        $wx = $model_class->getMbPaymentInfo(['payment_code'=>'wxpay_jsapi']);
        $this->appId = "wx25b984a617377a39";
        $this->appSecret = "d22c7cf9f6d2a2654540c18c7c3337eb";
    }


    public function getScan()
    {
        $config = $this->config(['scanQRCode'], false, false);
        $orderSn = request('order_sn','');
        return view('home.scan',compact('config','orderSn'));
    }

    /**
     * 获取JSSDK的配置数组.
     *
     * @param array $APIs
     * @param bool  $debug
     * @param bool  $json
     *
     * @return string|array
     */
    private function config(array $APIs, $debug = false, $beta = false, $json = true)
    {
        $signPackage = $this->getSignaturePackage();
        $base = array(
            'debug' => $debug,
            'beta' => $beta,
        );
        $config = array_merge($base, $signPackage, array('jsApiList' => $APIs));
        return $json ? $this->encode($config) : $config;
    }

    /**
     * 签名.
     *
     * @param string $url
     * @param string $nonce
     * @param int    $timestamp
     *
     * @return array
     */
    private function getSignaturePackage($url = null, $nonce = null, $timestamp = null)
    {
        $url = $url ? $url : $this->getUrl();
        $nonce = $nonce ? $nonce : $this->createNonceStr();
        $timestamp = $timestamp ? $timestamp : time();
        $ticket = $this->getTicket();

        $sign = array(
            'appId' => $this->appId,
            'nonceStr' => $nonce,
            'timestamp' => $timestamp,
            'url' => $url,
            'signature' => $this->getSignature($ticket, $nonce, $timestamp, $url),
        );

        return $sign;
    }

    /**
     * 生成签名.
     *
     * @param string $ticket
     * @param string $nonce
     * @param int    $timestamp
     * @param string $url
     *
     * @return string
     */
    private function getSignature($ticket, $nonce, $timestamp, $url)
    {
        return sha1("jsapi_ticket={$ticket}&noncestr={$nonce}&timestamp={$timestamp}&url={$url}");
    }


    /**
     * 获取当前URL.
     *
     * @return string
     */
    private function getUrl()
    {
        if ($this->url) {
            return $this->url;
        }

        return $this->current();
    }

    /**
     * 获取随机字符串.
     *
     * @return string
     */
    private function createNonceStr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }


    private function encode($value, $options = 0, $depth = 512)
    {
        // multi-characters supported by default
        $options |= JSON_UNESCAPED_UNICODE;

        $data = version_compare(PHP_VERSION, '5.5.0', '>=')
            ? json_encode($value, $options, $depth)
            : json_encode($value, $options);

        if (JSON_ERROR_NONE !== json_last_error()) {
            return $data;
        }

        return version_compare(PHP_VERSION, '5.4.0', '>=')
            ? $data
            : preg_replace_callback('/\\\\u([0-9a-f]{2})([0-9a-f]{2})/iu', function ($pipe) {
                return iconv(
                    strncasecmp(PHP_OS, 'WIN', 3) ? 'UCS-2BE' : 'UCS-2',
                    'UTF-8',
                    chr(hexdec($pipe[1])).chr(hexdec($pipe[2]))
                );
            }, $data);
    }

    /**
     * 获取当前URL
     *
     * @return string
     */
    private function current()
    {
        $protocol = (!empty($_SERVER['HTTPS'])
            && $_SERVER['HTTPS'] !== 'off'
            || $_SERVER['SERVER_PORT'] === 443) ? 'https://' : 'http://';

        if(isset($_SERVER['HTTP_X_FORWARDED_HOST'])){
            $host = $_SERVER['HTTP_X_FORWARDED_HOST'];
        }else{
            $host = $_SERVER['HTTP_HOST'];
        }
        return $protocol.$host.$_SERVER['REQUEST_URI'];
    }

    /**
     * 获取jsticket.
     *
     * @return string
     */
    private function getTicket() {
        $key = 'jsapi_ticket';
        // jsapi_ticket 应该全局存储与更新，以下代码以写入到文件中做示例
        $data = Cache::get($key);
        if ($data['expire_time'] < time()) {
            $accessToken = $this->getAccessToken();
            $url = self::API_TICKET."&access_token=$accessToken";
            $res = json_decode($this->httpGet($url));
            $ticket = $res->ticket;
            if ($ticket) {
                $data['expire_time'] = time() + 7000;
                $data['jsapi_ticket'] = $ticket;
                Cache::forever($key,$data);
            }
        } else {
            $ticket = $data['jsapi_ticket'];
        }
        return $ticket;
    }
    private function getAccessToken() {
        $key = 'access_token';
        // access_token 应该全局存储与更新，以下代码以写入到文件中做示例
        $data =Cache::get($key);
        if ($data['expire_time'] < time()) {
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
            $res = json_decode($this->httpGet($url));
            $access_token = $res->access_token;
            if ($access_token) {
                $data['expire_time'] = time() + 7000;
                $data['access_token'] = $access_token;
                Cache::forever($key,$data);
            }
        } else {
            $access_token = $data['access_token'];
        }
        return $access_token;
    }
    private function httpGet($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }

}
